class AudioPlayer {
  constructor (options) {
    this.audio = {}
    this.progress = {}
    if (options.audio && options.progress) {
      if (options.audio.el) this.audio.el = this.getEl(options.audio.el)
      if (options.audio.time) this.audio.time = this.getEl(options.audio.time)
      if (options.audio.playBtn) this.audio.playBtn = this.getEl(options.audio.playBtn)
      if (options.progress) {
        this.progress.el = this.getEl(options.progress.el)
        this.progress.current = this.getEl(options.progress.current)
        this.progress.select = this.getEl(options.progress.select)
        window.onTouch = false
      }
      /**
       * 设置进度条拖动事件
       */
      if (this.isMobile()) {
        this.progress.select.addEventListener('touchstart', this.onTouchStart.bind(this), false)
        document.addEventListener('touchmove', this.onTouchMove.bind(this), false)
        document.addEventListener('touchend', this.onTouchEnd.bind(this), false)
      } else {
        this.progress.select.addEventListener('mousedown', this.onTouchStart.bind(this), false)
        document.addEventListener('mousedown', this.onTouchMove.bind(this), false)
        document.addEventListener('mouseup', this.onTouchEnd.bind(this), false)
      }
      /**
       * 设置播放按钮点击事件
       */
      this.audio.playBtn.addEventListener('click', this.playBtnClick.bind(this), false)
      /**
       * 设置媒体元数据加载完成事件
       */
      this.audio.el.addEventListener('loadedmetadata', this.resetProgress.bind(this), false)
      /**
       * 设置更新播放进度事件
       */
      this.audio.el.addEventListener('timeupdate', this.updateProgress.bind(this), false)
      /**
       * 设置播放结束事件
       */
      this.audio.el.addEventListener('ended', this.stop.bind(this), false)
      /**
       * 设置自动播放
       */
      if (options.audio.autoPlay) this.audio.playBtn.click()
    } else {
      console.log('请传入参数')
    }
  }

  /**
   * 进度条拖动事件
   * @param e
   */
  onTouchStart (e) {
    window.onTouch = true
    window.progress = this.progress
    // 取消动画效果
    window.progress.current.style.webkitTransition =
      window.progress.current.style.transition =
        window.progress.select.style.webkitTransition =
          window.progress.select.style.transition = ''

    window.progress.startX = (e.clientX || e.touches[0].clientX) - window.progress.select.offsetLeft  //点击滑块内区域，即鼠标点击点距离元素左边缘的距离
    window.progress.maxLength = window.progress.el.offsetWidth  //移动最大距离
  }

  onTouchMove (e) {
    if (!window.onTouch || e.target !== this.progress.select) return // 若没有mousedown滑块，则mousemove不产生距离
    window.progress.moveX = e.clientX || e.touches[0].clientX
    /**
     * [moveLength 滑块移动总距离]
     * moveLength = moveX - startX ; //粗略值：滑块移动总距离
     * moveLength = Math.max(0,moveX - startX); //取0(初始left值)到moveL粗略值的中较大值，避免左侧滑出进度条范围
     * moveLength = Math.min(maxLength, moveLength); //取两者的最小值，避免右侧滑出进度条范围
     */
    window.progress.moveLength = Math.min(window.progress.maxLength, Math.max(0, window.progress.moveX - window.progress.startX))
    window.progress.current.style.width =
      window.progress.select.style.left = window.progress.moveLength + 'px'  //设置滑块left值
  }

  onTouchEnd (e) {
    if (!window.onTouch || e.target !== this.progress.select) return
    if (!isNaN(this.audio.el.duration * this.progress.moveLength / this.progress.el.offsetWidth))
      this.audio.el.currentTime = this.audio.el.duration * this.progress.moveLength / this.progress.el.offsetWidth
    window.onTouch = false
  }

  /**
   * 播放按钮点击事件
   */
  playBtnClick () {
    if (!window.audio || window.audio.el === this.audio.el) {
      window.audio = this.audio
      if (!this.audio.el.paused) this.pause(this.audio)
      else this.play(this.audio)
    } else {
      this.pause(window.audio)
      window.audio = this.audio
      this.play(this.audio)
    }
  }

  /**
   * 播放暂停
   * @param audio
   */
  pause (audio) {
    audio.el.pause()
    audio.playBtn.className = audio.playBtn.className.replace(' pause', ' play')
  }

  /**
   * 播放停止
   */
  stop () {
    this.pause(window.audio)
    window.audio.el.currentTime = 0
    this.resetProgress()
  }

  /**
   * 开始播放
   * @param audio
   */
  play (audio) {
    audio.el.play()
    audio.playBtn.className = audio.playBtn.className.replace(' play', ' pause')
  }

  /**
   * 更新进度条与当前播放时间
   */
  updateProgress () {
    const length = this.audio.el.currentTime * this.progress.el.offsetWidth / this.audio.el.duration
    if (!window.onTouch) {
      this.progress.current.style.webkitTransition =
        this.progress.current.style.transition = 'width 0.2s linear'
      this.progress.current.style.width = `${length}px`
      this.progress.select.style.webkitTransition =
        this.progress.select.style.transition = 'left 0.2s linear'
      this.progress.select.style.left = `${length}px`
    }
    this.audio.time.innerText = this.audio.el.duration - this.audio.el.currentTime > 0 ? `-${this.transTime(Math.max(this.audio.el.duration - this.audio.el.currentTime, 0))}` : '00:00'
  }

  /**
   * 重置进度条与当前播放时间
   */
  resetProgress () {
    if (!window.onTouch) {
      this.progress.current.style.webkitTransition =
        this.progress.current.style.transition =
          this.progress.select.style.webkitTransition =
            this.progress.select.style.transition = ''
      this.progress.current.style.width = this.progress.select.style.left = '0vw'
    }
    this.audio.time.innerText = this.audio.el.duration > 0 ? `-${this.transTime(this.audio.el.duration)}` : '--:--'
  }

  /**
   * 获取元素
   * @param el
   * @returns {Element}
   */
  getEl (el) {
    return typeof el === 'string' ? document.querySelector(el) : el
  }

  /**
   * 判断手机
   * @returns {boolean}
   */
  isMobile () {
    return navigator.userAgent.toLowerCase().indexOf('mobile') > -1
  }

  /**
   * 音频播放时间换算
   * @param {number} value - 音频当前播放时间，单位秒
   */
  transTime (time) {
    var h = parseInt(time / 3600)
    var m = parseInt((time % 3600) / 60)
    var s = parseInt((time % 3600) % 60)
    return h > 0 ? this.formatTime(h + ':' + m + ':' + s) : this.formatTime(m + ':' + s)
  }

  /**
   * 格式化时间显示，补零对齐
   * eg：2:4  -->  02:04
   * @param {string} value - 形如 h:m:s 的字符串
   */
  formatTime (value) {
    var time = ''
    var s = value.split(':')
    var i = 0
    for (; i < s.length - 1; i++) {
      time += s[i].length == 1 ? ('0' + s[i]) : s[i]
      time += ':'
    }
    time += s[i].length == 1 ? ('0' + s[i]) : s[i]
    return time
  }
}

window.AudioPlayer = AudioPlayer